<?php namespace xlx;

function aa(){ 
    echo '1';
    yield 'a';
    yield 'b';
    yield 'c'; 
}

$gen = aa();


echo (clone $gen)->current(); 
 
echo (clone $gen)->current(); 
 

echo (clone $gen)->current(); 
exit;
interface  Worker { 
    //-behaviour(gen_server). 
    //use GenServer
    function start_link();
    function terminate();
    function handle_call();
    function handle_cast();
    function handle_info();
    public function __construct();
}
class Task{
    public static function run($fn)                                    :Task{}
}
class Actor{
    public static function spawn($fn,$opt=[])                          :Actor{}
    public static function spawn_link($fn,$opt=[])                     :Actor{}
    public static function receive($timeout=-1 )                       :Promise{}
    public function send($pid,$msg,$opt=[])                            :void{} 
}
class GenServer{ 
    public static function start($class,$args=[],$opt=[]/*name:*/)     :GenServer{}
    public static function start_link($class,$args=[],$opt=[]/*name:*/):GenServer{}
    public static function call($class,$method,$args=[])               :Promise{}
    public static function cast($class,$method,$args=[])               :Promise{} 
}
class Supervisor{ 
    public static function start($childs)                              :Supervisor{}
    public static function start_link($childs,$opt=[]/*strategy:*/)    :Supervisor{}
}
class GenTcp{
    public function __construct($port){}
    public function accept(){}
    public function revc(){}
}

class TListen { 
    public function init($port){
        $server = new GenTcp($port);
        while(1){ 
            $client = yield GenTcp::accept($server); 
            Actor::spawn(self::request,[$client] ); 
        }
    } 
    public function request($client){
        while ($atom = yield Actor::receive() ) switch(true){
            case ($atom['tcp']) && ($atom[$client]) && ($atom['data']):
                yield GenServer::call(TClient::class,'aaaa',[$atom['data']]);
                break;
            case ($atom['tcp_closed']) && ($atom[$client]) :
                echo "E";
                break;
            default:
                break;
        } 
    } 
}
class TClient { 
    public function init($string){ 
        echo "init:".$string;
    } 
    public function aaaa($data){
        echo 'msg:',$data;
    }
}

//start
Supervisor::start_link([
    //gate
    Supervisor::start_link([ 
        GenServer::start_link(TListen::class,[8888]),  
    ]),
    //worker
    Supervisor::start_link([ 
        GenServer::start_link(TClient::class,['test']),
        GenServer::start_link(TClient::class,['test']),
        GenServer::start_link(TClient::class,['test']),
        GenServer::start_link(TClient::class,['test']),
    ])
]);
 